package com.manli.api.base.aop;

import com.manli.api.base.datasource.DynmicDataSourceContextHolder;
import com.manli.api.util.LogAopUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 切面到service
 * @author Shensg
 * 2018年5月31日
 */
@Aspect
@Order(-1)
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DataSourceAspect {
	private Logger log = LoggerFactory.getLogger(DataSourceAspect.class);  
	  
    ThreadLocal<Long> startTime = new ThreadLocal<>();  
  
    
    @Pointcut("execution(* com.manli.api.service..*Service.*(..))")
    public void webLog(){}  
  
    @Before("webLog()")  
    public void doBefore(JoinPoint joinPoint) throws Throwable {  
        startTime.set(System.currentTimeMillis());  
        String method = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
		String classType = joinPoint.getTarget().getClass().getName();
		Class<?> clazz = Class.forName(classType);
		String clazzName = clazz.getName();
		String methodName = joinPoint.getSignature().getName(); // 获取方法名称
		
		
        /*log.info("DataSourceAspect.doBefore 切面service");
        log.info("===============请求内容===============");
        log.info("切入点: " + joinPoint.getTarget().getClass().getName() + "类中"
				+ method + "方法");
    	// 获取参数名称和值
 		StringBuffer sb = LogAopUtil.getNameAndArgs(this.getClass(), clazzName, methodName, args);
 		log.info("请求类方法参数名称和值：" + sb);
 		log.info("===============请求内容===============");*/
        DynmicDataSourceContextHolder.clear();
		if (joinPoint.getTarget().getClass().getName().contains("Primary")) {
			if (method.startsWith("add")
					|| method.startsWith("create")
					|| method.startsWith("save")
					|| method.startsWith("edit")
					|| method.startsWith("update")
					|| method.startsWith("delete")
					|| method.startsWith("remove")
					|| method.startsWith("grant")
					|| method.startsWith("get")
					) {
				log.info("切换到: primaryDataSource");
				DynmicDataSourceContextHolder.setDataSourceKey("primaryDataSource"); 
				return;
			} else {
				log.info("切换到: primaryDataSource");
				DynmicDataSourceContextHolder.setDataSourceKey("primaryDataSource");
				return;
			}
		}
		if (joinPoint.getTarget().getClass().getName().contains("Second")) {
			log.info("切换到: secondDataSource");
			DynmicDataSourceContextHolder.setDataSourceKey("secondDataSource");
			return;
		}
		log.warn("没有分库操作,切换到默认库：primaryDataSource");
		DynmicDataSourceContextHolder.setDataSourceKey("primaryDataSource");
    }  
  
    @AfterReturning(returning = "ret", pointcut = "webLog()")  
    public void doAfterReturning(Object ret) throws Throwable {  
        // 处理完请求，返回内容  
    	/*log.info("===============响应内容===============");
    	log.info("DataSourceAspect.doAfterReturning 切面service");
        log.info("RESPONSE=" + ret);
        log.info("SPEND TIME=" + (System.currentTimeMillis() - startTime.get()));
        log.info("===============响应内容===============");*/
        DynmicDataSourceContextHolder.clear();
    }  
    // 抛出Exception之后被调用
    @AfterThrowing(throwing = "ex", pointcut = "webLog()") 
 	public void afterThrowing(Exception ex) throws Throwable {
    	DynmicDataSourceContextHolder.setDataSourceKey("primaryDataSource");
    	log.error("DataSourceAspect.afterThrowing 切面service");
 		log.error("数据操作出现异常,切换到: readParkingData"+ex.getMessage());
 	}
}
